home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Beginning Mac Programming
/
Beginning Mac Programming.bin
/
Open Me for REALbasic 3
/
REALbasic 3.2
/
Example Projects
/
Techniques
/
Examples by Thomas Tempelmann
/
TT's CatSearch-Plugin
/
Source Code (CW Pro 3)
/
Plugin Source.cpp
< prev
Wrap
Text File
|
1999-03-08
|
8KB
|
247 lines
/*
* Sample-Plugin showing how to pass structs from and to REALbasic-Plugins
*
* This plugin actually is useful:
* It allows you to search for files with a certain file type and/or file creator.
* This search is very fast (uses the same low-level function as the Finder's
* Find File aka Sherlock uses). However, some File Systems do not support this
* fast search method (called CatSearch): On Floppy Disks and on CD-ROMs with
* a ISO 9660 format this function might not work (depending on the File System
* driver you've installed). On plain HFS/HFS+ volumes, it should always work.
*
* This plugin works only with MacOS, neither with Windows nor with Java.
*
* The enclosed project file was created using CodeWarrior Pro 3.
* There's also a REALbasic Demo project that shows how to use this plugin.
*
* This code is freeware, you may use and extend it as you like.
*
* It was written on Feb 9, 99 by Thomas Tempelmann.
* More RB-related stuff can be found here: <http://www.tempel.org/rb>
*
* Update by TT on 12 Feb 99:
* • IsRemoteVolume() prevents crash by setting ioNamePtr to zero
*
* Update by TT on 8 Mar 99:
* • Renamed the plugin from "CatalogSearch-Plugin" to "TT's CatSearch-Plugin".
* • Added some more Catsearch-related functions.
* • Moved Catsearch-unrelated functions into a new plugin (called "TT's FileMgr-Plugin").
*
* Enjoy and contribute!
*/
#include <string.h>
#include "rb_plugin.h"
// this is the struct
typedef struct {
long check1;
long check[3]; // fill up to 16 byte boundary
char searchBuf[8192];
CSParam pb;
FSSpec spec;
CInfoPBRec info1;
CInfoPBRec info2;
Str27 volNameBuf;
long check2;
} CatSearchRec;
static Handle CatSearchOpen (REALfolderItem volIn)
// this creates the struct (allocates memory for it)
{
FSSpec fsSpec;
if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
Handle h = NewHandle (sizeof(CatSearchRec));
if (h && *h) {
// init the CatSearch fields
CatSearchRec *cs = (CatSearchRec*)*h;
CSParam &pb = cs->pb;
memset (cs, 0, sizeof (*cs));
pb.ioVRefNum = fsSpec.vRefNum;
pb.ioReqMatchCount = 1;
pb.ioOptBufSize = sizeof (cs->searchBuf);
cs->check1 = 'chk1';
cs->check2 = 'chk2';
// invalidate the pointers in the pb so that noone tries to access them:
pb.ioNamePtr = (StringPtr)0x41414141;
pb.ioMatchPtr = (FSSpec*)0x41414141;
pb.ioSearchInfo1 = (CInfoPBRec*)0x41414141;
pb.ioSearchInfo2 = (CInfoPBRec*)0x41414141;
pb.ioOptBuffer = (Ptr)0x41414141;
return h;
}
}
return nil;
}
static void CatSearchClose (Handle h)
// this releases the memory for the struct again
{
if (h) {
CatSearchRec *cs = (CatSearchRec*)*h;
if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
} else {
DisposeHandle (h);
}
}
}
static long CatSearchSetFileType (Handle h, REALstring fileType)
// this sets some of the struct's values
{
if (h) {
CatSearchRec *cs = (CatSearchRec*)*h;
if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
} else {
const unsigned char* ftStr = REALPString (fileType);
OSType ftype = *(OSType*)&ftStr[1];
cs->info1.hFileInfo.ioFlFndrInfo.fdType = ftype;
cs->info2.hFileInfo.ioFlFndrInfo.fdType = (UInt32) -1; // mask
cs->info1.hFileInfo.ioFlAttrib &= ~ioDirMask; // looking for files, not dirs
cs->info2.hFileInfo.ioFlAttrib |= ioDirMask; // set the mask for files/dirs
cs->pb.ioSearchBits |= fsSBFlAttrib | fsSBFlFndrInfo;
return 1;
}
}
return 0;
}
static long CatSearchSetCreator (Handle h, REALstring creator)
// this sets some of the struct's values
{
if (h) {
CatSearchRec *cs = (CatSearchRec*)*h;
if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
} else {
const unsigned char* cr = REALPString (creator);
OSType fc = *(OSType*)&cr[1];
cs->info1.hFileInfo.ioFlFndrInfo.fdCreator = fc;
cs->info2.hFileInfo.ioFlFndrInfo.fdCreator = (UInt32) -1; // mask
cs->info1.hFileInfo.ioFlAttrib &= ~ioDirMask; // looking for files, not dirs
cs->info2.hFileInfo.ioFlAttrib |= ioDirMask; // set the mask for files/dirs
cs->pb.ioSearchBits |= fsSBFlAttrib | fsSBFlFndrInfo;
return 1;
}
}
return 0;
}
static long CatSearchSetFileFlags (Handle h, long mask, long selector)
// this adds specific File Flags to the Search Selection
{
if (h) {
CatSearchRec *cs = (CatSearchRec*)*h;
if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
} else {
cs->info1.hFileInfo.ioFlFndrInfo.fdFlags = (cs->info1.hFileInfo.ioFlFndrInfo.fdFlags & ~mask) | (selector & mask);
cs->info2.hFileInfo.ioFlFndrInfo.fdFlags |= mask;
cs->info1.hFileInfo.ioFlAttrib &= ~ioDirMask; // looking for files, not dirs
cs->info2.hFileInfo.ioFlAttrib |= ioDirMask; // set the mask for files/dirs
cs->pb.ioSearchBits |= fsSBFlAttrib | fsSBFlFndrInfo;
return 1;
}
}
return 0;
}
static long CatSearchNext (Handle h)
// this performs the real action
{
if (h) {
CatSearchRec *cs = (CatSearchRec*)*h;
if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
} else {
// since the CatSearchRec buffer might have been moved (it's not locked), we must
// set the pointers right before they're accessed:
CSParam &pb = cs->pb;
pb.ioNamePtr = cs->volNameBuf;
pb.ioMatchPtr = &cs->spec;
pb.ioSearchInfo1 = &cs->info1;
pb.ioSearchInfo2 = &cs->info2;
pb.ioOptBuffer = cs->searchBuf;
OSErr err = PBCatSearchSync (&cs->pb);
// invalidate them again so that noone tries to access them:
pb.ioNamePtr = (StringPtr)0x41414141;
pb.ioMatchPtr = (FSSpec*)0x41414141;
pb.ioSearchInfo1 = (CInfoPBRec*)0x41414141;
pb.ioSearchInfo2 = (CInfoPBRec*)0x41414141;
pb.ioOptBuffer = (Ptr)0x41414141;
return err;
}
}
return -1;
}
static REALfolderItem CatSearchGetItem (Handle h)
// this retrieves one of the struct's values
{
if (h) {
CatSearchRec *cs = (CatSearchRec*)*h;
if (cs->check1 != 'chk1' || cs->check2 != 'chk2') {
DebugStr ("\pError in CatSearch-Plugin: bad handle passed");
} else {
return REALFolderItemFromFSSpec (&cs->spec);
}
}
return NULL;
}
static long VolSupportsCatSearch (REALfolderItem volIn)
{
FSSpec fsSpec;
if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
IOParam pb;
GetVolParmsInfoBuffer buf;
pb.ioVRefNum = fsSpec.vRefNum;
pb.ioBuffer = (Ptr)&buf;
pb.ioReqCount = 6;
pb.ioNamePtr = nil;
if (PBHGetVolParmsSync ((HParmBlkPtr)&pb) == noErr && pb.ioActCount >= 6) {
if ((buf.vMAttrib & bHasCatSearch) != 0) return 1;
}
}
return 0;
}
REALexport pluginExports[] = {
{ nil, CatSearchOpen },
{ nil, CatSearchClose },
{ nil, CatSearchSetFileType },
{ nil, CatSearchSetCreator },
{ nil, CatSearchNext },
{ nil, CatSearchGetItem },
{ nil, CatSearchSetFileFlags },
{ nil, VolSupportsCatSearch },
};
short pluginExportCode = sizeof(pluginExports) / sizeof(REALexport);
REALmethodDefinition methods[] = {
{0, "CatSearchOpen(volume as FolderItem) as Integer"},
{1, "CatSearchClose(handle as Integer)"},
{2, "CatSearchSetFileType(handle as Integer, fileType as String) as Boolean"},
{3, "CatSearchSetCreator(handle as Integer, creator as String) as Boolean"},
{4, "CatSearchNext(handle as Integer) as Integer"},
{5, "CatSearchGetItem(handle as Integer) as FolderItem"},
{6, "CatSearchSetFileFlags(handle as Integer, mask as Integer, selector as Integer) as Boolean"},
{7, "VolSupportsCatSearch(volume as FolderItem) as Boolean"},
};
void PluginEntry (void)
{
for (int i = 0; i < pluginExportCode; ++i) {
REALRegisterMethod (&methods[i]);
}
}